package com.example.controller.redis;


import com.example.service.redis.TestService;
import com.example.pojo.vo.common.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;


/**
 * @author LiYuhang
 * @version 0.1
 * @application cache TestController
 * CacheAside Pattern
 * 读 先读缓存 缓存没有 读数据库
 * 写 先写数据库 再删除缓存
 * @Date 2020/9/23 10:34
 */
@RestController
@RequestMapping("test2")
@Slf4j(topic = "CACHE-TestController2")
public class TestController2 {

    @Autowired
    TestService testService;

    /**
     * 支持 SpEL 表达式
     */

    /**
     *  存放数据
     *  key = test::111222333
     * @param param1
     * @param param2
     * @param param3
     * @return
     */
    @RequestMapping(value = "search")
    @CachePut(value = "test", key = "#param1 + #param2 + #param3")
    public Result search(String param1,String param2,String param3){
        log.info("#######,{}", "param1 = [" + param1 + "], param2 = [" + param2 + "], param3 = [" + param3 + "]");
        List<String> data=testService.getDataList();
        return Result.OK(data);
    }

    @RequestMapping(value = "search1")
    @Cacheable(value = "test",keyGenerator ="keyGenerator" )
    public Result search1(String param1,String param2,String param3){
        log.info("#######,{}", "param1 = [" + param1 + "], param2 = [" + param2 + "], param3 = [" + param3 + "]");
        List<String> data=testService.getDataList();
        return Result.OK(data);
    }

    /**
     *  Cacheable
     *   先读缓存 如果缓存没有   再往下执行 并把这个接口返回结果 放入缓存在
     *  key = test::111222333
     *  1、首先执行@CacheEvict（如果beforeInvocation=true且condition 通过），如果allEntries=true，则清空所有
     * 2、接着收集@Cacheable（如果condition 通过，且key对应的数据不在缓存），放入cachePutRequests（也就是说如果cachePutRequests为空，则数据在缓存中）
     * 3、如果cachePutRequests为空且没有@CachePut操作，那么将查找@Cacheable的缓存，否则result=缓存数据（也就是说只要当没有cache put请求时才会查找缓存）
     * 4、如果没有找到缓存，那么调用实际的API，把结果放入result
     * 5、如果有@CachePut操作(如果condition 通过)，那么放入cachePutRequests
     * 6、执行cachePutRequests，将数据写入缓存（unless为空或者unless解析结果为false）；
     * 7、执行@CacheEvict（如果beforeInvocation=false 且 condition 通过），如果allEntries=true，则清空所有
     * @param param1
     * @param param2
     * @param param3
     * @return
     */

    @RequestMapping(value = "search2")
    @Cacheable(value = "test", key = "#param1 + #param2 + #param3")
    public Result search2(String param1,String param2,String param3){
        log.info("#######,{}", "param1 = [" + param1 + "], param2 = [" + param2 + "], param3 = [" + param3 + "]");
        List<String> data=testService.getDataList();
        return Result.OK(data);
    }

    @RequestMapping(value = "search3")
    @Cacheable(value = "test")
    public Result search3(String param1,String param2,String param3){
        log.info("#######,{}", "param1 = [" + param1 + "], param2 = [" + param2 + "], param3 = [" + param3 + "]");
        List<String> data=testService.getDataList();
        return Result.OK(data);
    }


    /**
     * ge(>=)、gt(>)、lt(<)、le(<=)、eq(==)、ne(!=)、div(/)、mod(%)、not(!)
     * @param param1
     * @param param2
     * @param param3
     * @param param4
     * @return
     */
    @RequestMapping(value = "search4")
    @Cacheable(value = "test",condition = "#param4 ne 'test' ")
    public Result search4(String param1,String param2,String param3,String param4){
        log.info("#######,{}", "param1 = [" + param1 + "], param2 = [" + param2 + "], param3 = [" + param3 + "]");
        List<String> data=testService.getDataList();
        return Result.OK(data);
    }


    /**
     * 移除所有数据
     */
    @RequestMapping(value = "write1")
    @CacheEvict(value = "test", allEntries = true)
    public Result write1(){
        //write to Database
        boolean flag=testService.writToDb();
        if(flag){
            return Result.OK("数据更新成功");
        }else{
            return Result.error("数据修改失败");
        }
    }

    /**
     * 移除指定key的数据
     */
    @CacheEvict(value = "test", key = "#key")
    @RequestMapping(value = "write2")
    public Result write2(String key){
        //write to Database
        boolean flag=testService.writToDb();
        if(flag){
            return Result.OK("数据更新成功");
        }else{
            return Result.error("数据修改失败");
        }
    }
}
